Skip to content

files: extract page header component#1608

Open
ivaavimusic wants to merge 4 commits intorecoupable:testfrom
ivaavimusic:ui-polish-upload-guidance
Open

files: extract page header component#1608
ivaavimusic wants to merge 4 commits intorecoupable:testfrom
ivaavimusic:ui-polish-upload-guidance

Conversation

@ivaavimusic
Copy link
Copy Markdown
Contributor

@ivaavimusic ivaavimusic commented Mar 30, 2026

Summary

This PR improves the Files page by adding a clear page header and short upload guidance.

Changes

  • adds a dedicated FilesPageHeader component
  • renders the header above the existing sandbox file tree
  • adds short guidance about the kinds of files users can upload for their agent

Why

The Files page previously had no title or context, which made the upload area feel ambiguous. This adds lightweight guidance without changing the underlying file flow.

Risk

Low. This is a small page-level UI change limited to header content and spacing.

@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Mar 30, 2026

@ivaavimusic is attempting to deploy a commit to the Recoupable Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 30, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3989c555-97e2-42a4-b9cd-b549f420f485

📥 Commits

Reviewing files that changed from the base of the PR and between 2745a69 and 034cae1.

📒 Files selected for processing (1)
  • components/Sandboxes/FilesPageHeader.tsx
✅ Files skipped from review due to trivial changes (1)
  • components/Sandboxes/FilesPageHeader.tsx

📝 Walkthrough

Walkthrough

This change adds a new FilesPageHeader component and renders it above the existing file tree on the files page, adjusting the page container to include vertical spacing between the header and the file tree.

Changes

Cohort / File(s) Summary
New Header Component
components/Sandboxes/FilesPageHeader.tsx
Adds a default-exported FilesPageHeader React component rendering a "Files" title and descriptive paragraph for uploading repository files.
Files Page Integration
app/files/page.tsx
Imports and renders FilesPageHeader above SandboxFileTree and adds space-y-6 to the outer container to provide vertical spacing.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

Poem

A little header takes its place,
Above the tree, it sets the pace.
Files welcomed with a gentle line,
Neat spacing keeps the layout fine. ✨

🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Solid & Clean Code ✅ Passed The PR demonstrates excellent adherence to SOLID & Clean Code principles with a minimal, self-documenting FilesPageHeader component following Single Responsibility and Open/Closed principles.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bdc06008f9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +34 to +35
if (!disableInternalScroll) {
return;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reset textarea height when disabling autosize mode

When disableInternalScroll flips from true to false (e.g., after sending the first message), adjustHeight exits early and never clears the inline textarea.style.height previously set during autosizing. This leaves the composer stuck at an expanded height even after the input is cleared, so the post-send chat input can remain oversized until remount. Add a reset path for the non-autosize branch (or whenever the flag changes) so height returns to the normal controlled size.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
components/Sandboxes/NoSandboxFiles.tsx (1)

24-30: Optional: remove duplicated width constraint to reduce style drift.

max-w-md is applied on both wrapper and root dropzone; keeping it in one place makes future layout changes safer.

♻️ Suggested simplification
-      <div
+      <div
         {...getRootProps()}
         role="region"
         aria-label="File upload dropzone"
         className={cn(
-          "w-full max-w-md rounded-lg p-8 border-2 border-dashed transition-all",
+          "w-full rounded-lg p-8 border-2 border-dashed transition-all",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/Sandboxes/NoSandboxFiles.tsx` around lines 24 - 30, The dropzone
has a duplicated width constraint: the outer wrapper div and the inner element
using {...getRootProps()} both include "max-w-md", which can cause style drift;
remove "max-w-md" from the inner element's className (the element that spreads
getRootProps()) and keep it on the outer wrapper div so the width constraint is
defined in a single place, ensuring future layout changes are safer.
components/Sidebar/RecentChats/ChatItem.tsx (1)

155-182: Align menu keyboard behavior with role="menu" semantics.

This menu currently handles Escape, but not arrow-key navigation/focus movement expected for menu patterns. Either implement full menu keyboard behavior or switch to semantics that match current interaction.

As per coding guidelines, "Support arrow key navigation in dropdown menu components" and "Implement proper focus management in dropdown menu components".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/Sidebar/RecentChats/ChatItem.tsx` around lines 155 - 182, The menu
currently uses role="menu" but only handles Escape; update ChatItem.tsx to
either implement proper menu keyboard/focus behavior or change semantics to
match current interactions: either (A) implement arrow-key focus movement and
roving focus inside the menu when isMenuOpen (manage focus on menuRef and menu
items, handle ArrowDown/ArrowUp to move focus between the buttons, Home/End to
jump, and Escape to close via onMenuToggle) and ensure the buttons
(onRenameClick, onDeleteClick) are focusable and have role="menuitem" and
appropriate aria-activedescendant/aria-controls as needed, or (B) remove
role="menu" and use role="listbox" or no menu role to reflect basic click-only
behavior; pick one approach and update ChatItem's menuRef, isMenuOpen
conditional, onMenuToggle, onRenameClick and onDeleteClick accordingly to
maintain correct focus cleanup when closing.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@components/VercelChat/FileMentionsInput.tsx`:
- Around line 33-45: The adjustHeight callback exits early when
disableInternalScroll is false, leaving any previously set inline textarea
height intact; update adjustHeight (and callers if needed) so that when
disableInternalScroll is false it clears the inline height on the element
referenced by inputRef (e.g., set textarea.style.height = "" or "auto") before
returning, ensuring the composer resets to its default height; reference the
adjustHeight function, the disableInternalScroll flag, and
inputRef/textarea.style.height when making the change.

---

Nitpick comments:
In `@components/Sandboxes/NoSandboxFiles.tsx`:
- Around line 24-30: The dropzone has a duplicated width constraint: the outer
wrapper div and the inner element using {...getRootProps()} both include
"max-w-md", which can cause style drift; remove "max-w-md" from the inner
element's className (the element that spreads getRootProps()) and keep it on the
outer wrapper div so the width constraint is defined in a single place, ensuring
future layout changes are safer.

In `@components/Sidebar/RecentChats/ChatItem.tsx`:
- Around line 155-182: The menu currently uses role="menu" but only handles
Escape; update ChatItem.tsx to either implement proper menu keyboard/focus
behavior or change semantics to match current interactions: either (A) implement
arrow-key focus movement and roving focus inside the menu when isMenuOpen
(manage focus on menuRef and menu items, handle ArrowDown/ArrowUp to move focus
between the buttons, Home/End to jump, and Escape to close via onMenuToggle) and
ensure the buttons (onRenameClick, onDeleteClick) are focusable and have
role="menuitem" and appropriate aria-activedescendant/aria-controls as needed,
or (B) remove role="menu" and use role="listbox" or no menu role to reflect
basic click-only behavior; pick one approach and update ChatItem's menuRef,
isMenuOpen conditional, onMenuToggle, onRenameClick and onDeleteClick
accordingly to maintain correct focus cleanup when closing.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 022d880d-fae1-416f-b459-4fcafde4208e

📥 Commits

Reviewing files that changed from the base of the PR and between 0a6fc82 and bdc0600.

📒 Files selected for processing (9)
  • app/files/page.tsx
  • components/Sandboxes/NoSandboxFiles.tsx
  • components/Sidebar/NewChatButton.tsx
  • components/Sidebar/RecentChats/ChatItem.tsx
  • components/VercelChat/ChatInput.tsx
  • components/VercelChat/FileMentionsInput.tsx
  • components/VercelChat/mentionsStyles.ts
  • components/ui/button.tsx
  • components/ui/dialog.tsx

@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Mar 30, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
recoup-chat Ready Ready Preview Mar 31, 2026 3:11am

Request Review

Comment on lines +5 to +13
<div className="px-6 md:px-12 py-8 space-y-6">
<div className="max-w-3xl">
<h1 className="text-left font-heading text-3xl font-bold">
Files
</h1>
<p className="mt-2 text-lg text-muted-foreground font-light font-sans">
Upload repository files for your agent sandbox, including code, docs, assets, and reference material.
</p>
</div>
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Single Responsibility / Open Closed Principles

  • actual: adding net new code to an existing component.
  • required: new component file for the Header code.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. I’ll keep the header improvement but move it into a separate component file.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the state of missing files, we actually want these files to get setup via the Sandbox task.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood. I was approaching this as a general empty-state improvement, but I see that the intended flow is different here. I’ll revert this file from the PR for now and keep missing-files UX as a separate follow-up.

}}
className={cn(
"shrink-0 w-4 h-4 rounded border-2 transition-all duration-150 flex items-center justify-center",
"shrink-0 w-4 h-4 rounded border-2 transition-all duration-150 flex items-center justify-center cursor-pointer",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Single Responsibility Principle

  • why are you modifying chatItem in a pull request titled upload-guidance?
  • Each pull request should improve exactly one thing.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. This is unrelated to upload guidance. I’ll remove it from this PR and keep it for a separate UI polish PR.

type="button"
className={cn(
"inline-flex items-center h-10 rounded-lg whitespace-nowrap overflow-hidden transition-all duration-200 text-sm font-normal text-foreground hover:bg-muted",
"inline-flex items-center h-10 rounded-lg whitespace-nowrap overflow-hidden transition-all duration-200 text-sm font-normal text-foreground hover:bg-muted cursor-pointer",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same SRP question here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I’ll move this out of the PR so the scope stays focused.


const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-xl text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-xl text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 cursor-pointer",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not modify root shadcn components.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood.

>
{children}
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground cursor-pointer">
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not modify root shadcn components.

onChange={setInput}
disabled={isDisabled || hasPendingUploads}
model={model}
disableInternalScroll={messages.length === 0}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SRP - why are you modifying chat components in a pr titled for file uploads?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point. This belongs in a separate PR, not this one. I’ll remove it from here.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please summarize what the purpose of these changes are and how they contribute to the title of the PR?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You’re right to call this out. This was a misunderstood change on my side and it does not meaningfully contribute to the scope or title of this PR. I’ll remove it

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of these file changes?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file changed only in support of the same misunderstood change above, so it does not belong in this PR either. I’ll remove this as well.

@ivaavimusic ivaavimusic changed the title Polish upload affordances and file page guidance Extract files page header into dedicated component Mar 30, 2026
@ivaavimusic ivaavimusic changed the title Extract files page header into dedicated component files: extract page header component Mar 30, 2026
<div className="max-w-3xl">
<h1 className="text-left font-heading text-3xl font-bold">Files</h1>
<p className="mt-2 text-lg text-muted-foreground font-light font-sans">
Upload repository files for your agent sandbox, including code, docs,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Upload repository files for your agent sandbox, including code, docs,
Upload repository files for your agent, including images, songs,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants